#!/usr/bin/env python
# -*- coding:utf-8 -*-

import ssl
import socket
import urllib
from lib.utils.printer import *
import urllib.request
#全局取消证书验证
if hasattr(ssl,'__create_unverified_context'):
    ssl._create_default_https_context = ssl._create_unverified_context

def BasicAuthCredentials(creds):
    return tuple(
        creds.split(":")
    )

def ProxyDict(proxy):
    return {
        'http' : proxy,
        'https' : proxy
    }

class Request(object):
    def __init__(self,*kwargs):
        self.kwargs = kwargs
    
    def Send(self, url, method="get", data=None, headers=None):
        _dict_ = self.kwargs[0]
        auth =  None if "auth" not in _dict_ else _dict_["auth"]
        agent = None if "agent" not in _dict_ else _dict_["agent"]
        proxy = None if "proxy" not in _dict_ else _dict_["proxy"]
        pauth = None if "pauth" not in _dict_ else _dict_["pauth"]
        cookie = None if "cookie" not in _dict_ else _dict_["cookie"]
        timeout = None if "timeout" not in _dict_ else _dict_['timeout']
        redirect = True if "redirect" not in _dict_ else _dict_["redirect"]
        _headers_ = None if "headers" not in _dict_ else _dict_["headers"]
        _data_ = None if "data" not in _dict_ else _dict_["data"]
        _method_ = None if "method" not in _dict_ else _dict_["method"]
        if method:
            if _method_ != None:
                method = _method_.upper()
            else:
                method = method.upper()
        
        if data is None:
            if _data_ != None:
                data = _data_
            else:
                data = {}
        
        if headers is None:
            headers = {}

        if auth is None:
            auth = ()
        
        if 'User-Agent' not in headers:
            headers['User-Agent'] = agent
        if isinstance(_headers_,dict):
            headers.update(_headers_)
        
        if auth != None and auth != ():
            if ':' in auth:
                authorization = ("%s:%s"%(BasicAuthCredentials(auth))).encode('base64')
                headers['Authorization'] = "Basic %s"%(authorization.replace('\n',''))
        
        if pauth != None:
            if ':' in pauth:
                proxy_authorization = ("%s:%s"%(BasicAuthCredentials(pauth))).encode('base64')
                headers['Proxy-authorization'] = "Basic %s"%(proxy_authorization.replace('\n',''))
        
        if timeout != None:
            socket.setdefaulttimeout(timeout)
        #处理 http,https
        handlers = [urllib.request.HTTPHandler(),urllib.request.HTTPSHandler()]

        if 'Cookie' not in headers:
            if cookie != None and cookie != "":
                headers['Cookie']  = cookie
        
        if redirect != True:
            handlers.append(NoRedirectHandler)
        
        if proxy:
            proxies = ProxyDict(proxy)
            handlers.append(urllib.request.ProxyHandler(proxies=proxies))
        opener = urllib.request.build_opener(*handlers)
        urllib.request.install_opener(opener)

        if method == "GET":
            if data:
                url = "%s?%s"%(url,data)
            req = urllib.request.Request(url,headers=headers)
        elif method == "POST":
            if isinstance(data,str):
                data = data.encode('utf-8')
            req = urllib.request.Request(url,data=data,headers=headers)
        else:
            req = urllib.request.Request(url,headers=headers)
            req.get_method = lambda : method
        try:
            resp = urllib.request.urlopen(req)
        except urllib.request.HTTPError as e:
            resp = e
        except socket.error as e:
            exit(warn("错误: %s"%e))
        except urllib.request.URLError as e:
            exit(warn("错误: %s"%e))
        return ResponseObject(resp)
        
class ResponseObject(object):
    def __init__(self,resp):
        self.content = resp.read().decode('utf-8')
        self.url = resp.geturl()
        self.code = resp.getcode()
        self.headers = self.headers_dict(resp)
    def headers_dict(self,resp):
        headers = {}
        for k,v in resp.getheaders():
            headers[k] = v
        return headers

class NoRedirectHandler(urllib.request.HTTPRedirectHandler):
    def http_error_302(self, req, fp, code, msg, headers):
        pass
    http_error_302 = http_error_302 = http_error_302 = http_error_302

